package com.faxsun.core.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import mblog.core.persist.dao.CommentDao;
import mblog.core.persist.dao.PostDao;
import mblog.core.persist.dao.TagDao;
import mblog.core.pojos.Comment;
import mblog.core.pojos.Post;
import mblog.core.pojos.Product;
import mblog.core.pojos.Tag;
import mblog.core.utils.BeanMapUtils;
import mtons.modules.pojos.Page;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import com.faxsun.core.persist.entity.CommentPO;
import com.faxsun.core.persist.entity.PostPO;
import com.faxsun.core.persist.entity.TagPO;
import com.faxsun.core.pojos.enums.ConstantTags;
import com.faxsun.core.service.AggregationService;
import com.faxsun.core.service.CommentService;
import com.faxsun.core.service.IndexService;
import com.faxsun.pojos.TagAggregation;

public class IndexServiceImpl implements IndexService {

	private static final Logger log = LoggerFactory
			.getLogger(IndexServiceImpl.class);

	@Autowired
	private TagDao tagDao;

	@Autowired
	private AggregationService aggregationService;

	@Autowired
	private CommentDao commentDao;

	@Autowired
	private PostDao postDao;

	@Override
	@Transactional(readOnly = true)
	public List<Product> retrieveRecommendProducts(Page page) {
		List<TagPO> recommendProductTag = tagDao
				.findForRecommendProductsTag(page.getMaxResults());
		List<Product> products = new ArrayList<Product>();
		for (TagPO tagPO : recommendProductTag) {
			Tag tag = BeanMapUtils.copy(tagPO);
			/* Assert.notNull(tagPO.getProductRef()); */
			Product product = BeanMapUtils.copy(tagPO.getProductRef());
			// product.setFavorite(tag.getFollowsCounts());
			product.setTag(tag);
			products.add(product);
		}
		page.setResults(products);
		return products;
	}

	@Override
	@Transactional(readOnly = true)
	public List<Post> retrieveHotEvluation(Page page) {
		TagAggregation tagAggregation = aggregationService
				.aggregateEvulationsByTag(page, ConstantTags.HOT);
		assert tagAggregation.getEvaluations() != null;
		page.setResults(tagAggregation.getEvaluations());
		return tagAggregation.getEvaluations();
	}

	@Override
	@Transactional(readOnly = true)
	public List<Post> retrieveHotInfo(Page page) {
		TagAggregation tagAggregation = aggregationService.aggregateInfosByTag(
				page, ConstantTags.HOT);
		assert tagAggregation.getInfos() != null;
		page.setResults(tagAggregation.getInfos());
		return tagAggregation.getInfos();
	}

	@Override
	@Transactional(readOnly = true)
	public List<Comment> retrieveNewestComment(Page page) {
		List<CommentPO> list = commentDao.retrieveNewest(page);

		List<Long> toPostIds = new ArrayList<Long>(list != null ? list.size()
				: 0);
		List<Long> toTagIds = new ArrayList<Long>(list != null ? list.size()
				: 0);

		List<Comment> rets = new ArrayList<Comment>();
		for (CommentPO po : list) {
			rets.add(BeanMapUtils.copy(po));
			if (po.getType() == 0) {
				toTagIds.add(po.getToId());
			} else {
				toPostIds.add(po.getToId());
			}
		}

		Map<Long, PostPO> toPostsMap = new HashMap<Long, PostPO>();
		if (toPostIds.size() > 0) {
			List<PostPO> toPosts = postDao.findByIds(toPostIds);
			for (PostPO post : toPosts) {
				toPostsMap.put(post.getId(), post);
			}
		}

		Map<Long, TagPO> toTagsMap = new HashMap<Long, TagPO>();
		if (toTagIds.size() > 0) {
			List<TagPO> toTags = tagDao.findByIds(toTagIds);
			for (TagPO tag : toTags) {
				toTagsMap.put(tag.getId(), tag);
			}
		}

		for (Comment cmt : rets) {
			if (cmt.getType() == 0) {
				cmt.setToTag(BeanMapUtils.copy(toTagsMap.get(cmt.getToId())));
			} else {
				cmt.setToPost(BeanMapUtils.copy(toPostsMap.get(cmt.getToId()),
						1));
			}
			if (cmt.getContent().contains(CommentService.REPLY_TOKEN)) {
				String[] tmp = cmt.getContent().split(
						CommentService.REPLY_TOKEN);
				if (tmp.length != 3) {
					log.error("Reply comment has error:" + cmt.getContent());
				}
				if (tmp.length < 3) {
					cmt.setContent("回复" + tmp[1] + ":");
				} else {
					cmt.setContent("回复" + tmp[1] + ":" + tmp[2]);
				}
			}
		}

		page.setResults(rets);
		return rets;
	}

	@Override
	@Transactional(readOnly = true)
	public Map<Long, List<Product>> retrieveTopProductsByCategory(
			List<Tag> categories, int topNum) {

		Map<Long, List<Product>> result = new HashMap<Long, List<Product>>();
		if (categories == null || topNum < 1) {

		} else {
			for (Tag category : categories) {
				List<TagPO> tags = tagDao.findRecommendProductsForCategory(
						category, topNum);

				result.put(category.getId(), BeanMapUtils.copy(tags, 1));
			}
		}
		return result;
	}

}
